package com.kstudio.videocapture.listfile.fileaction;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;

import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.Message;

import com.kstudio.videocapture.util.KLog;

public class KFileActionUtil {
    private final KLog log = new KLog("KFileList");

    public static final String      MODE        = "FileActionMode";
    public static final String      PATH        = "FileActionPath";

    public static final int         MODE_COPY   = 0x0001;
    public static final int         MODE_MOVE   = 0x0002;
    public static final int         MODE_DELETE = 0x0003;

    private static final int        MSG_PROGRESS   = 0x0001;
    private static final int        MSG_COMPLETE   = 0x0002;
    private static final int        MSG_ERROR      = 0x0003;

    private FileActionThread        mThread;
    private KFileActionUtilListener mListener;

    public interface KFileActionUtilListener {
        void onProgress(int time);
        void onComplete();
        void onError();
    }

    public static void copy(Context c, String path) {
        Intent intent = new Intent(c, KFileActionActivity.class);
        intent.putExtra(MODE, MODE_COPY);
        intent.putExtra(PATH, path);
        c.startActivity(intent);
    }

    public static void move(Context c, String path) {
        Intent intent = new Intent(c, KFileActionActivity.class);
        intent.putExtra(MODE, MODE_MOVE);
        intent.putExtra(PATH, path);
        c.startActivity(intent);
    }

    public static void delete(String path, KFileActionUtilListener l) {
        new KFileActionUtil(MODE_DELETE, path, l);
    }

    private final Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_PROGRESS:
                    progress(0);
                break;
                case MSG_COMPLETE:
                    complete();
                break;
                case MSG_ERROR:
                    error();
                break;
            }
        }
    };

    public KFileActionUtil(int mode, String source, KFileActionUtilListener l) {
        this(mode, source, null, l);
    }

    public KFileActionUtil(int mode, String source, String target, KFileActionUtilListener l) {
        mListener = l;

        mThread = new FileActionThread(mode, source, target);
        mThread.start();
    }

    public void stop() {
        mThread.stopThread();
    }

    private void progress(int progress) {
        if(mListener != null) mListener.onProgress(progress);
    }

    private void complete() {
        if(mListener != null) mListener.onComplete();
    }

    private void error() {
        if(mListener != null) mListener.onError();
    }

    private class FileActionThread extends Thread {
        private int     mMode;
        private String  mSource;
        private String  mTaget;

        public boolean running;

        public void stopThread() {
            running = false;
        }

        public FileActionThread(int mode, String source, String target) {
            super();
            running = true;

            mMode = mode;
            mSource = source;
            mTaget = target;
        }

        @Override
        public void run() {
            while(running) {
                if(mMode == MODE_COPY) {
                    File sourceFile = new File(mSource);

                    FileInputStream inputStream = null;
                    FileOutputStream outputStream = null;
                    FileChannel fcin = null;
                    FileChannel fcout = null;

                    try {
                        inputStream = new FileInputStream(sourceFile);
                        outputStream = new FileOutputStream(mTaget);

                        fcin = inputStream.getChannel();
                        fcout = outputStream.getChannel();

                        long size = fcin.size();
                        fcin.transferTo(0, size, fcout);

                        running = false;
                        mHandler.sendEmptyMessage(MSG_COMPLETE);
                    } catch (Exception e) {
                        e.printStackTrace();
                        mHandler.sendEmptyMessage(MSG_ERROR);
                    } finally {
                        try { fcout.close();} catch (IOException ioe) {}
                        try { fcin.close(); } catch (IOException ioe) {}
                        try { outputStream.close();} catch (IOException ioe) {}
                        try { inputStream.close(); } catch (IOException ioe) {}
                    }
                } else if(mMode == MODE_MOVE) {
                    log.d("MODE_MOVE mSource = %s mTaget = %s", mSource, mTaget);
                    File sourceFile = new File(mSource);
                    File tagetFile  = new File(mTaget);

                    sourceFile.renameTo(tagetFile);
                    log.d("MODE_MOVE renameTo");

                    running = false;
                    mHandler.sendEmptyMessage(MSG_COMPLETE);
                } else if(mMode == MODE_DELETE) {
                    File sourceFile = new File(mSource);

                    if(sourceFile.exists())
                        sourceFile.delete();

                    running = false;
                    mHandler.sendEmptyMessage(MSG_COMPLETE);
                }
            }
        }

        @SuppressWarnings("unused")
        private void streamCopy(String source, String target) {
            File sourceFile = new File( source );

            FileInputStream inputStream = null;
            FileOutputStream outputStream = null;

            try {
                inputStream = new FileInputStream(sourceFile);
                outputStream = new FileOutputStream(target);

                int bytesRead = 0;

                byte[] buffer = new byte[1024];
                while ((bytesRead = inputStream.read(buffer, 0, 1024)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally{
                try{
                    outputStream.close();
                }catch(IOException ioe){

                }

                try{
                    inputStream.close();
                }catch(IOException ioe){

                }
            }
        }

        @SuppressWarnings("unused")
        private void bufferCopy(String source, String target) {
              File sourceFile = new File(source);

              FileInputStream inputStream = null;
              FileOutputStream outputStream = null;
              BufferedInputStream bin = null;
              BufferedOutputStream bout = null;

              try {
                  inputStream = new FileInputStream(sourceFile);
                  outputStream = new FileOutputStream(target);

                  bin = new BufferedInputStream(inputStream);
                  bout = new BufferedOutputStream(outputStream);

                  int bytesRead = 0;
                  byte[] buffer = new byte[1024];
                  while ((bytesRead = bin.read(buffer, 0, 1024)) != -1) {
                      bout.write(buffer, 0, bytesRead);
                  }
              } catch (Exception e) {
                  e.printStackTrace();
              } finally {
                  try{
                      outputStream.close();
                  }catch(IOException ioe){

                  }
                  try{
                      inputStream.close();
                  }catch(IOException ioe){

                  }
                  try{
                      bin.close();
                  }catch(IOException ioe){

                  }

                  try{
                      bout.close();
                  }catch(IOException ioe){

                  }
              }
        }

        @SuppressWarnings("unused")
        private void ChannelCopy(String source, String target) {
            File sourceFile = new File(source);

            FileInputStream inputStream = null;
            FileOutputStream outputStream = null;
            FileChannel fcin = null;
            FileChannel fcout = null;

            try {
                inputStream = new FileInputStream(sourceFile);
                outputStream = new FileOutputStream(target);

                fcin = inputStream.getChannel();
                fcout = outputStream.getChannel();

                long size = fcin.size();
                fcin.transferTo(0, size, fcout);

            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    fcout.close();
                } catch (IOException ioe) {

                }
                try {
                    fcin.close();
                } catch (IOException ioe) {

                }
                try {
                    outputStream.close();
                } catch (IOException ioe) {

                }
                try {
                    inputStream.close();
                } catch (IOException ioe) {

                }
            }
        }

    }
}
